import sys
import os
import time
import threading
import signal
from datetime import datetime
import queue
from concurrent.futures import ThreadPoolExecutor
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, 
                             QHBoxLayout, QGridLayout, QLabel, QPushButton, 
                             QComboBox, QSpinBox, QGroupBox, QScrollArea, 
                             QMessageBox, QStatusBar, QFrame)
from PyQt6.QtCore import Qt, QTimer, pyqtSignal, QThread
from PyQt6.QtGui import QPixmap, QImage, QPainter, QFont
import pyautogui
import cv2
import numpy as np
from PIL import Image
from websocket_server import get_websocket_server
from winapi_capture import capture_window_winapi, get_all_windows_winapi

class ImageDisplayWidget(QWidget):
    """图像显示组件"""
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setMinimumSize(400, 300)
        self.setStyleSheet("background-color: white; border: 1px solid #ccc;")
        
        # 创建标签用于显示图像
        self.image_label = QLabel()
        self.image_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.image_label.setText("等待捕获图像...")
        self.image_label.setStyleSheet("color: #666; font-size: 14px;")
        
        # 创建滚动区域
        self.scroll_area = QScrollArea()
        self.scroll_area.setWidget(self.image_label)
        self.scroll_area.setWidgetResizable(True)
        
        # 设置布局
        layout = QVBoxLayout(self)
        layout.addWidget(self.scroll_area)
        self.setLayout(layout)
        
        self.current_pixmap = None
    
    def display_image(self, pil_image, quality_setting="平衡"):
        """显示PIL图像"""
        try:
            if pil_image is None:
                return
                
            # 获取组件尺寸
            widget_width = self.width()
            widget_height = self.height()
            
            if widget_width > 1 and widget_height > 1:
                # 计算缩放比例
                img_width, img_height = pil_image.size
                scale_x = widget_width / img_width
                scale_y = widget_height / img_height
                scale = min(scale_x, scale_y, 1.0)  # 不放大，只缩小
                
                # 根据质量设置调整缩放策略
                if quality_setting == "最高质量":
                    min_scale = max(0.6, scale)
                elif quality_setting == "高质量":
                    min_scale = max(0.5, scale)
                elif quality_setting == "平衡":
                    min_scale = max(0.4, scale)
                else:  # 高性能
                    min_scale = max(0.3, scale)
                
                # 应用最小缩放限制
                if scale < min_scale:
                    scale = min_scale
                
                # 应用缩放
                if scale < 1.0:
                    new_width = int(img_width * scale)
                    new_height = int(img_height * scale)
                    
                    # 根据质量设置选择缩放算法
                    if quality_setting in ["最高质量", "高质量"]:
                        pil_image = pil_image.resize((new_width, new_height), Image.Resampling.LANCZOS)
                    elif quality_setting == "平衡":
                        pil_image = pil_image.resize((new_width, new_height), Image.Resampling.BOX)
                    else:  # 高性能
                        pil_image = pil_image.resize((new_width, new_height), Image.Resampling.NEAREST)
            
            # 转换为QImage
            if pil_image.mode == "RGB":
                qimage = QImage(pil_image.tobytes(), pil_image.width, pil_image.height, 
                               pil_image.width * 3, QImage.Format.Format_RGB888)
            else:
                pil_image = pil_image.convert("RGB")
                qimage = QImage(pil_image.tobytes(), pil_image.width, pil_image.height, 
                               pil_image.width * 3, QImage.Format.Format_RGB888)
            
            # 创建QPixmap并显示
            self.current_pixmap = QPixmap.fromImage(qimage)
            self.image_label.setPixmap(self.current_pixmap)
            
        except Exception as e:
            QMessageBox.critical(self, "错误", f"显示图像失败: {str(e)}")

class ContinuousCaptureThread(QThread):
    """连续捕获线程 - 使用队列机制优化帧率控制"""
    frame_captured = pyqtSignal(object)  # 发送捕获的帧
    fps_updated = pyqtSignal(float)      # 发送FPS更新
    
    def __init__(self, window_title, fps, is_fullscreen=False):
        super().__init__()
        self.window_title = window_title
        self.fps = fps
        self.is_fullscreen = is_fullscreen
        self.is_running = False
        
        # 队列机制
        self.frame_queue = queue.Queue(maxsize=5)  # 最多缓存5帧
        self.capture_thread = None
        self.output_thread = None
        
        # 帧率控制
        self.target_frame_interval = 1.0 / self.fps  # 目标帧间隔
        self.next_output_time = time.time()  # 下一帧输出时间
        
        # 统计信息
        self.frame_count = 0
        self.last_fps_time = time.time()
        self.capture_times = []  # 捕获时间记录
        self.max_capture_times = 30
        self.last_debug_time = time.time()
        
        # 性能统计
        self.captured_frames = 0  # 捕获的帧数
        self.output_frames = 0    # 输出的帧数
        self.dropped_frames = 0   # 丢弃的帧数
        self.queue_full_count = 0 # 队列满的次数
    
    def run(self):
        """运行连续捕获 - 使用队列机制"""
        self.is_running = True
        self.next_output_time = time.time()
        
        print(f"开始连续捕获 - 目标帧率: {self.fps} FPS, 帧间隔: {self.target_frame_interval:.3f}s")
        print("使用队列机制: 捕获线程和输出线程分离，提高帧率精度")
        
        # 启动捕获线程
        self.capture_thread = threading.Thread(target=self._capture_loop, daemon=True)
        self.capture_thread.start()
        
        # 启动输出线程
        self.output_thread = threading.Thread(target=self._output_loop, daemon=True)
        self.output_thread.start()
        
        # 等待线程结束
        if self.capture_thread:
            self.capture_thread.join()
        if self.output_thread:
            self.output_thread.join()
        
        print("捕获线程已停止")
    
    def _capture_loop(self):
        """捕获循环 - 持续捕获帧并放入队列"""
        print("捕获线程已启动")
        
        while self.is_running:
            frame_start_time = time.time()
            
            try:
                # 使用WinAPI捕获（支持被遮挡的窗口）
                img = capture_window_winapi(self.window_title, self.is_fullscreen)
                
                # 记录捕获时间
                capture_time = time.time() - frame_start_time
                self.capture_times.append(capture_time)
                if len(self.capture_times) > self.max_capture_times:
                    self.capture_times.pop(0)
                
                if img:
                    # 尝试将帧放入队列
                    try:
                        # 非阻塞方式放入队列
                        self.frame_queue.put_nowait({
                            'image': img,
                            'timestamp': time.time(),
                            'capture_time': capture_time
                        })
                        self.captured_frames += 1
                        
                    except queue.Full:
                        # 队列满了，丢弃最旧的帧，放入新帧
                        try:
                            self.frame_queue.get_nowait()  # 移除最旧的帧
                            self.frame_queue.put_nowait({
                                'image': img,
                                'timestamp': time.time(),
                                'capture_time': capture_time
                            })
                            self.captured_frames += 1
                            self.dropped_frames += 1
                            self.queue_full_count += 1
                        except queue.Empty:
                            # 队列已空，直接放入
                            self.frame_queue.put_nowait({
                                'image': img,
                                'timestamp': time.time(),
                                'capture_time': capture_time
                            })
                            self.captured_frames += 1
                else:
                    # 如果捕获失败，短暂等待后重试
                    time.sleep(0.01)
                    
            except Exception as e:
                print(f"捕获循环错误: {e}")
                time.sleep(0.01)
    
    def _output_loop(self):
        """输出循环 - 按固定时间间隔从队列取帧并输出"""
        print("输出线程已启动")
        
        while self.is_running:
            current_time = time.time()
            sleep_time = self.next_output_time - current_time
            
            if sleep_time > 0:
                # 等待到输出时间
                if sleep_time > 0.001:  # 大于1ms使用sleep
                    time.sleep(sleep_time)
                else:
                    # 小于1ms使用忙等待
                    while time.time() < self.next_output_time:
                        pass
            
            # 尝试从队列获取帧
            try:
                frame_data = self.frame_queue.get_nowait()
                img = frame_data['image']
                
                # 发送帧数据
                self.frame_captured.emit(img)
                self.output_frames += 1
                
                # 计算实时帧率
                self.frame_count += 1
                current_time = time.time()
                if current_time - self.last_fps_time >= 1.0:
                    actual_fps = self.frame_count / (current_time - self.last_fps_time)
                    self.fps_updated.emit(actual_fps)
                    
                    # 每5秒输出一次调试信息
                    if current_time - self.last_debug_time >= 5.0:
                        self._print_performance_stats(actual_fps)
                        self.last_debug_time = current_time
                    
                    self.frame_count = 0
                    self.last_fps_time = current_time
                
            except queue.Empty:
                # 队列为空，没有可输出的帧
                self.dropped_frames += 1
                if time.time() - self.last_debug_time >= 5.0:
                    print("警告: 输出队列为空，无帧可输出")
            
            # 更新下一帧输出时间
            self.next_output_time += self.target_frame_interval
    
    def _print_performance_stats(self, actual_fps):
        """打印性能统计信息"""
        avg_capture_time = sum(self.capture_times) / len(self.capture_times) if self.capture_times else 0
        queue_size = self.frame_queue.qsize()
        
        print(f"性能监控 - 实际FPS: {actual_fps:.1f}, 目标FPS: {self.fps}")
        print(f"          - 队列状态: {queue_size}/5, 捕获帧数: {self.captured_frames}, 输出帧数: {self.output_frames}")
        print(f"          - 平均捕获时间: {avg_capture_time*1000:.1f}ms, 丢帧数: {self.dropped_frames}")
        print(f"          - 队列满次数: {self.queue_full_count}")
        
        # 性能建议
        if actual_fps < self.fps * 0.8:
            print(f"          - 建议: 实际帧率低于目标，考虑降低帧率或优化捕获")
        elif queue_size == 0:
            print(f"          - 建议: 队列经常为空，捕获速度可能不足")
        elif self.queue_full_count > 10:
            print(f"          - 建议: 队列经常满，输出速度可能不足")
    
    def stop(self):
        """停止连续捕获"""
        self.is_running = False
    
    def update_target(self, window_title, is_fullscreen=False):
        """更新捕获目标"""
        self.window_title = window_title
        self.is_fullscreen = is_fullscreen
    
    def update_fps(self, fps):
        """更新帧率"""
        self.fps = fps
        self.target_frame_interval = 1.0 / fps
        print(f"帧率已更新为: {fps} FPS, 帧间隔: {self.target_frame_interval:.3f}s")
        
        # 清空队列和统计信息
        while not self.frame_queue.empty():
            try:
                self.frame_queue.get_nowait()
            except queue.Empty:
                break
        
        # 重置统计
        self.captured_frames = 0
        self.output_frames = 0
        self.dropped_frames = 0
        self.queue_full_count = 0

class WindowCapture(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("窗口捕获工具 - WinAPI版")
        self.setGeometry(100, 100, 900, 700)
        
        # 初始化变量
        self.captured_image = None
        self.is_capturing = False
        self.continuous_capture_thread = None
        
        # 初始化WebSocket服务器
        self.websocket_server = get_websocket_server()
        self.websocket_enabled = False
        
        # 创建线程池用于WebSocket传输（增加编码线程）
        self.websocket_executor = ThreadPoolExecutor(max_workers=8, thread_name_prefix="websocket")
        
        # WebSocket传输队列，避免阻塞
        self.websocket_queue = queue.Queue(maxsize=3)  # 最多缓存3帧
        self.websocket_worker_thread = None
        self.websocket_worker_running = False
        
        # 设置信号处理
        self.setup_signal_handlers()
        
        # 自动启动WebSocket服务器
        try:
            self.websocket_server.start_server()
            self.websocket_enabled = True
            # 设置WebSocket帧率，避免过度传输
            self.websocket_server.set_websocket_fps(120)  # 提高到120 FPS
            print("WebSocket服务器已自动启动 (端口: 8765, 帧率: 120 FPS)")
        except Exception as e:
            print(f"WebSocket服务器启动失败: {e}")
            self.websocket_enabled = False
        
        # 启动WebSocket工作线程
        self.start_websocket_worker()
        
        # 设置UI
        self.setup_ui()
        
        # 初始化
        self.refresh_windows()
        
        # 启动WebSocket状态更新定时器
        self.websocket_timer = QTimer()
        self.websocket_timer.timeout.connect(self.update_websocket_status)
        self.websocket_timer.start(1000)
        
        # 程序启动时自动开始连续捕获全屏
        QTimer.singleShot(1000, lambda: self.start_continuous_capture("", is_fullscreen=True))
    
    def setup_signal_handlers(self):
        """设置信号处理器"""
        def signal_handler(signum, frame):
            print(f"收到信号 {signum}，正在关闭程序...")
            self.close()
        
        # 注册信号处理器
        signal.signal(signal.SIGINT, signal_handler)   # Ctrl+C
        signal.signal(signal.SIGTERM, signal_handler)  # 终止信号
    
    def setup_ui(self):
        """设置用户界面"""
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        # 主布局
        main_layout = QVBoxLayout(central_widget)
        main_layout.setSpacing(10)
        main_layout.setContentsMargins(10, 10, 10, 10)
        
        # 窗口选择区域
        window_group = QGroupBox("窗口选择")
        window_layout = QHBoxLayout()
        
        window_layout.addWidget(QLabel("选择窗口:"))
        self.window_combo = QComboBox()
        self.window_combo.setMinimumWidth(400)
        self.window_combo.currentTextChanged.connect(self.on_window_selection_changed)
        window_layout.addWidget(self.window_combo)
        
        refresh_btn = QPushButton("刷新窗口列表")
        refresh_btn.clicked.connect(self.refresh_windows)
        window_layout.addWidget(refresh_btn)
        
        window_group.setLayout(window_layout)
        main_layout.addWidget(window_group)
        
        # 捕获控制区域
        control_group = QGroupBox("捕获控制")
        control_layout = QGridLayout()
        
        # 第一行：帧率设置
        control_layout.addWidget(QLabel("捕获帧率:"), 0, 0)
        self.fps_spinbox = QSpinBox()
        self.fps_spinbox.setRange(1, 60)
        self.fps_spinbox.setValue(30)
        self.fps_spinbox.valueChanged.connect(self.on_fps_changed)
        control_layout.addWidget(self.fps_spinbox, 0, 1)
        control_layout.addWidget(QLabel("FPS"), 0, 2)
        
        # 第二行：质量设置
        control_layout.addWidget(QLabel("图像质量:"), 1, 0)
        self.quality_combo = QComboBox()
        self.quality_combo.addItems(["最高质量", "高质量", "平衡", "高性能"])
        self.quality_combo.setCurrentText("平衡")
        self.quality_combo.currentTextChanged.connect(self.on_quality_changed)
        control_layout.addWidget(self.quality_combo, 1, 1)
        control_layout.addWidget(QLabel("(1080p优先)"), 1, 2)
        
        # 第三行：WebSocket状态显示
        control_layout.addWidget(QLabel("WebSocket状态:"), 2, 0)
        self.websocket_status = QLabel("运行中")
        self.websocket_status.setStyleSheet("color: green;")
        control_layout.addWidget(self.websocket_status, 2, 1)
        control_layout.addWidget(QLabel("(端口: 8765)"), 2, 2)
        
        control_group.setLayout(control_layout)
        main_layout.addWidget(control_group)
        
        # 图像显示区域
        image_group = QGroupBox("捕获预览")
        image_layout = QVBoxLayout()
        
        self.image_display = ImageDisplayWidget()
        image_layout.addWidget(self.image_display)
        
        image_group.setLayout(image_layout)
        main_layout.addWidget(image_group, 1)  # 设置拉伸因子为1
        
        # 状态栏
        self.setup_status_bar()
    
    def setup_status_bar(self):
        """设置状态栏"""
        status_bar = self.statusBar()
        
        # 分辨率信息
        self.resolution_label = QLabel("分辨率: 未捕获")
        self.resolution_label.setFrameStyle(QFrame.Shape.StyledPanel)
        status_bar.addWidget(self.resolution_label)
        
        # 状态信息
        self.status_label = QLabel("就绪")
        self.status_label.setFrameStyle(QFrame.Shape.StyledPanel)
        status_bar.addWidget(self.status_label)
        
        # WebSocket连接信息
        self.websocket_info = QLabel("WebSocket: 0 连接")
        self.websocket_info.setFrameStyle(QFrame.Shape.StyledPanel)
        status_bar.addWidget(self.websocket_info)

    def refresh_windows(self):
        """刷新窗口列表"""
        try:
            # 使用WinAPI获取窗口列表
            windows_data = get_all_windows_winapi()
            windows = [w['title'] for w in windows_data if w['title'].strip()]
            
            # 清空并添加选项
            self.window_combo.clear()
            # 添加"全屏捕获"选项
            self.window_combo.addItem("全屏捕获")
            # 添加所有窗口
            self.window_combo.addItems(windows)
            
            # 默认选择"全屏捕获"
            self.window_combo.setCurrentIndex(0)
            self.status_label.setText(f"找到 {len(windows)} 个窗口，已添加全屏捕获选项")
        except Exception as e:
            QMessageBox.critical(self, "错误", f"获取窗口列表失败: {str(e)}")
            self.status_label.setText("获取窗口列表失败")
    
    def on_window_selection_changed(self, window_title):
        """窗口选择变化时的处理"""
        if window_title and window_title.strip():
            # 检查是否为全屏捕获
            if window_title == "全屏捕获":
                self.status_label.setText("切换到全屏捕获模式")
                # 更新连续捕获的目标为全屏
                if self.continuous_capture_thread and self.continuous_capture_thread.isRunning():
                    self.continuous_capture_thread.update_target("", is_fullscreen=True)
                else:
                    # 如果没有运行连续捕获，启动全屏捕获
                    self.start_continuous_capture("", is_fullscreen=True)
            else:
                self.status_label.setText(f"切换到窗口: {window_title}")
                # 更新连续捕获的目标为指定窗口
                if self.continuous_capture_thread and self.continuous_capture_thread.isRunning():
                    self.continuous_capture_thread.update_target(window_title, is_fullscreen=False)
                else:
                    # 如果没有运行连续捕获，启动窗口捕获
                    self.start_continuous_capture(window_title, is_fullscreen=False)
    
    def on_quality_changed(self, quality):
        """图像质量变化时的处理"""
        if self.captured_image:
            self.display_image(self.captured_image)
            self.status_label.setText(f"图像质量已更新为: {quality}")
    
    def on_fps_changed(self, fps):
        """帧率变化时的处理"""
        if self.continuous_capture_thread and self.continuous_capture_thread.isRunning():
            self.continuous_capture_thread.update_fps(fps)
            self.status_label.setText(f"帧率已更新为: {fps} FPS")
    
    
    def start_continuous_capture(self, window_title=None, is_fullscreen=False):
        """启动连续捕获"""
        if self.is_capturing:
            return
            
        # 停止之前的捕获线程
        if self.continuous_capture_thread and self.continuous_capture_thread.isRunning():
            self.continuous_capture_thread.stop()
            self.continuous_capture_thread.wait()
        
        # 确定捕获目标
        if not is_fullscreen and not window_title:
            window_title = self.window_combo.currentText()
            if window_title == "全屏捕获":
                is_fullscreen = True
                window_title = ""
        
        # 创建并启动连续捕获线程
        fps = self.fps_spinbox.value()
        self.continuous_capture_thread = ContinuousCaptureThread(window_title, fps, is_fullscreen)
        self.continuous_capture_thread.frame_captured.connect(self.handle_captured_frame)
        self.continuous_capture_thread.fps_updated.connect(self.update_fps_display)
        self.continuous_capture_thread.start()
        
        self.is_capturing = True
        if is_fullscreen:
            self.status_label.setText("连续捕获已启动 - 全屏模式")
        else:
            self.status_label.setText(f"连续捕获已启动 - 窗口: {window_title}")
    
    def stop_continuous_capture(self):
        """停止连续捕获"""
        if self.continuous_capture_thread and self.continuous_capture_thread.isRunning():
            print("正在停止捕获线程...")
            self.continuous_capture_thread.stop()
            # 等待线程结束，最多等待2秒
            if not self.continuous_capture_thread.wait(2000):
                print("捕获线程未在2秒内结束，强制终止...")
                self.continuous_capture_thread.terminate()
                self.continuous_capture_thread.wait(1000)
        
        self.is_capturing = False
        self.status_label.setText("连续捕获已停止")
    
    def handle_captured_frame(self, img):
        """处理捕获的帧"""
        # 显示图像
        self.display_image(img)
        
        # 更新分辨率显示
        self.update_resolution_display(img)
        
        # 通过WebSocket广播帧
        self.broadcast_frame_to_websocket(img)
    
    def update_fps_display(self, fps):
        """更新帧率显示"""
        if fps > 0:
            self.status_label.setText(f"连续捕获中 - 实时帧率: {fps:.1f} FPS")
    

    

    
    def update_resolution_display(self, img):
        """更新分辨率显示"""
        if img:
            width, height = img.size
            # 判断分辨率等级
            # if width >= 1920 and height >= 1080:
            #     quality = "1080p+ (高清)"
            # elif width >= 1280 and height >= 720:
            #     quality = "720p (标清)"
            # elif width >= 800 and height >= 600:
            #     quality = "VGA+"
            # else:
            #     quality = "低分辨率"
            
            self.resolution_label.setText(f"分辨率: {width}×{height}")
        else:
            self.resolution_label.setText("分辨率: 未捕获")
    
    def display_image(self, img):
        """显示图像"""
        self.captured_image = img.copy()
        
        quality = self.quality_combo.currentText()
        self.image_display.display_image(img, quality)
    
    def update_websocket_status(self):
        """更新WebSocket状态信息"""
        if self.websocket_enabled and self.websocket_server.is_server_running():
            client_count = self.websocket_server.get_client_count()
            self.websocket_info.setText(f"WebSocket: {client_count} 连接")
            # 更新状态标签
            if client_count > 0:
                self.websocket_status.setText(f"运行中 ({client_count} 连接)")
                self.websocket_status.setStyleSheet("color: green;")
            else:
                self.websocket_status.setText("运行中 (等待连接)")
                self.websocket_status.setStyleSheet("color: green;")
        else:
            self.websocket_info.setText("WebSocket: 启动失败")
            self.websocket_status.setText("启动失败")
            self.websocket_status.setStyleSheet("color: red;")
    
    def start_websocket_worker(self):
        """启动WebSocket工作线程"""
        if not self.websocket_worker_running:
            self.websocket_worker_running = True
            self.websocket_worker_thread = threading.Thread(target=self._websocket_worker, daemon=True)
            self.websocket_worker_thread.start()
            print("WebSocket工作线程已启动")
    
    def stop_websocket_worker(self):
        """停止WebSocket工作线程"""
        self.websocket_worker_running = False
        if self.websocket_worker_thread:
            self.websocket_worker_thread.join(timeout=1)
            print("WebSocket工作线程已停止")
    
    def _websocket_worker(self):
        """WebSocket工作线程主循环"""
        while self.websocket_worker_running:
            try:
                # 从队列获取图像，超时1秒
                image = self.websocket_queue.get(timeout=1)
                if image is not None:
                    # 使用线程池进行并行编码和传输
                    self.websocket_executor.submit(self._do_websocket_encode_and_send, image)
                self.websocket_queue.task_done()
            except queue.Empty:
                continue
            except Exception as e:
                print(f"WebSocket工作线程错误: {e}")
    
    def _do_websocket_encode_and_send(self, image):
        """在线程池中执行图像编码和传输"""
        try:
            # 在子线程中进行图像拷贝和编码
            image_copy = image.copy()
            self.websocket_server.broadcast_frame(image_copy)
        except Exception as e:
            print(f"WebSocket编码传输错误: {e}")
    
    def broadcast_frame_to_websocket(self, image):
        """通过WebSocket广播帧数据（使用队列机制）"""
        if self.websocket_enabled and self.websocket_server.is_server_running():
            try:
                # 非阻塞方式放入队列
                self.websocket_queue.put_nowait(image)
            except queue.Full:
                # 队列满了，丢弃最旧的帧
                try:
                    self.websocket_queue.get_nowait()
                    self.websocket_queue.put_nowait(image)
                except queue.Empty:
                    pass
            except Exception as e:
                print(f"WebSocket广播帧失败: {e}")
    
    
    def closeEvent(self, event):
        """程序关闭事件"""
        print("正在关闭程序...")
        
        # 停止连续捕获
        self.stop_continuous_capture()
        
        # 停止WebSocket工作线程
        self.stop_websocket_worker()
        
        # 停止WebSocket服务器
        if self.websocket_enabled:
            try:
                self.websocket_server.stop_server()
                print("WebSocket服务器已停止")
            except Exception as e:
                print(f"停止WebSocket服务器时出错: {e}")
        
        # 关闭WebSocket线程池
        try:
            self.websocket_executor.shutdown(wait=False)
            print("WebSocket线程池已关闭")
        except Exception as e:
            print(f"关闭WebSocket线程池时出错: {e}")
        
        # 等待所有线程结束
        if self.continuous_capture_thread and self.continuous_capture_thread.isRunning():
            print("等待捕获线程结束...")
            self.continuous_capture_thread.quit()
            self.continuous_capture_thread.wait(3000)  # 等待最多3秒
            if self.continuous_capture_thread.isRunning():
                print("强制终止捕获线程...")
                self.continuous_capture_thread.terminate()
                self.continuous_capture_thread.wait(1000)
        
        print("程序已安全关闭")
        event.accept()
